// @Author miaoqing
// @Date 2024/02/22 17:26:00
// @Desc
package logic

import (
	"core/common"
	"core/component/function"
	"core/component/logger"
	"sync"
	"sync/atomic"
)

var (
	cmOnce        sync.Once
	clientManager *ClientManager
)

type ClientManager struct {
	clients        *sync.Map
	robots         int32
	userID2Clients *sync.Map
}

func clientManagerGetMe() *ClientManager {
	cmOnce.Do(func() {
		clientManager = &ClientManager{
			clients:        &sync.Map{},
			userID2Clients: &sync.Map{},
		}
	})
	return clientManager
}

// online服务器断线,暂时先断开玩家连接(TODO:后期需要通知玩家切线)

func (mgr *ClientManager) bindUserID2Client(userID uint64, c *Client) {
	_, ok := mgr.userID2Clients.Load(userID)
	if ok {
		logger.Warningf("bind user %v already exist", userID)
	}
	mgr.userID2Clients.Store(userID, c)
}

func (mgr *ClientManager) unbindUserID2Client(userID uint64) {
	mgr.userID2Clients.Delete(userID)
}

func (mgr *ClientManager) getBindUserID2Client(userID uint64) *Client {
	val, ok := mgr.userID2Clients.Load(userID)
	if !ok {
		return nil
	}
	return val.(*Client)
}

func (mgr *ClientManager) sendMsgToClient(robotID uint64, cmd int, data []byte) bool {
	client := mgr.getBindUserID2Client(robotID)
	if client == nil {
		return false
	}
	msgSendData := &common.MsgSendData{
		Cmd:  cmd,
		Data: string(data),
	}
	msByte, err := function.MyMarshal(msgSendData)
	if err != nil {
		return false
	}
	return client.AsyncSendRowMsg(msByte)
}

func (mgr *ClientManager) addClient(connID int64, c *Client) {
	_, ok := mgr.clients.Load(connID)
	if ok {
		return
	}
	mgr.clients.Store(connID, c)
	atomic.AddInt32(&mgr.robots, 1)
	c.onUserVerify(uint64(connID))
}

func (mgr *ClientManager) removeClient(clientID int64) {
	_, ok := mgr.clients.Load(clientID)
	if !ok {
		return
	}
	mgr.clients.Delete(clientID)
	atomic.AddInt32(&mgr.robots, -1)
}
